package com.huahai.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huahai.exception.BusinessException;
import com.huahai.exception.ErrorCode;
import com.huahai.mapper.SpaceUserMapper;
import com.huahai.pojo.dto.spaceuser.SpaceUserAddDTO;
import com.huahai.pojo.dto.spaceuser.SpaceUserQueryDTO;
import com.huahai.pojo.entity.Space;
import com.huahai.pojo.entity.SpaceUser;
import com.huahai.pojo.entity.User;
import com.huahai.pojo.enums.SpaceRoleEnum;
import com.huahai.pojo.vo.space.SpaceVO;
import com.huahai.pojo.vo.spaceuser.SpaceUserVO;
import com.huahai.pojo.vo.user.UserVO;
import com.huahai.service.SpaceService;
import com.huahai.service.SpaceUserService;
import com.huahai.service.UserService;
import com.huahai.util.ThrowUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author huahai
 * @description 针对表【space_user(空间用户关联)】的数据库操作Service实现
 * @createDate 2025-08-11 16:24:01
 */
@Service
public class SpaceUserServiceImpl extends ServiceImpl<SpaceUserMapper, SpaceUser> implements SpaceUserService {

    @Resource
    private SpaceService spaceService;

    @Resource
    private UserService userService;

    /**
     * 创建团队空间用户信息
     *
     * @param spaceUserAddDTO 创建团队空间用户参数
     * @return 创建的空间id
     */
    @Override
    public Long addSpaceUser(SpaceUserAddDTO spaceUserAddDTO) {
        // 1. 校验参数
        ThrowUtils.throwIf(spaceUserAddDTO == null, ErrorCode.PARAMS_ERROR);
        SpaceUser spaceUser = new SpaceUser();
        BeanUtils.copyProperties(spaceUserAddDTO, spaceUser);
        this.validSpaceUser(spaceUser, true);
        // 2. 校验当前要创建的用户是否已经加入了空间
        boolean exists = this.lambdaQuery().eq(SpaceUser::getUserId, spaceUser.getUserId())
                .eq(SpaceUser::getSpaceId, spaceUser.getSpaceId())
                .exists();
        ThrowUtils.throwIf(exists, ErrorCode.OPERATION_ERROR, "当前邀请用户已加入空间");
        // 3. 创建空间用户信息
        boolean saveResult = this.save(spaceUser);
        ThrowUtils.throwIf(!saveResult, ErrorCode.OPERATION_ERROR, "创建空间用户失败");
        return spaceUser.getId();
    }

    /**
     * spaceUser类型转换脱敏（单个团队空间）
     *
     * @param spaceUser 空间用户对象
     * @param request   请求
     * @return SpaceUserVO 脱敏后的团队空间用户信息
     */
    @Override
    public SpaceUserVO getSpaceUserVO(SpaceUser spaceUser, HttpServletRequest request) {
        // 1. 转换成脱敏后的信息
        SpaceUserVO spaceUserVO = SpaceUserVO.objToVo(spaceUser);
        // 2. 封装关联条件
        User user = userService.getById(spaceUser.getUserId());
        ThrowUtils.throwIf(user == null, ErrorCode.NOT_FOUND_ERROR, "用户不存在");
        UserVO userVO = userService.getUserVO(user);
        spaceUserVO.setUser(userVO);

        Space space = spaceService.getById(spaceUser.getSpaceId());
        ThrowUtils.throwIf(space == null, ErrorCode.NOT_FOUND_ERROR, "空间不存在");
        SpaceVO spaceVO = spaceService.getSpaceVO(space, request);
        spaceUserVO.setSpace(spaceVO);
        // 3. 封装返回
        return spaceUserVO;
    }

    /**
     * 获取团队空间用户信息封装
     *
     * @param spaceUserList 团队空间用户列表
     * @return List<SpaceUserVO> 脱敏后的团队空间用户信息列表
     */
    @Override
    public List<SpaceUserVO> getSpaceUserVOList(List<SpaceUser> spaceUserList) {
        // 判断输入列表是否为空
        if (CollUtil.isEmpty(spaceUserList)) {
            return Collections.emptyList();
        }
        // 对象列表 => 封装对象列表
        List<SpaceUserVO> spaceUserVOList = spaceUserList.stream().map(SpaceUserVO::objToVo).collect(Collectors.toList());
        // 1. 收集需要关联查询的用户 ID 和空间 ID
        Set<Long> userIdSet = spaceUserList.stream().map(SpaceUser::getUserId).collect(Collectors.toSet());
        Set<Long> spaceIdSet = spaceUserList.stream().map(SpaceUser::getSpaceId).collect(Collectors.toSet());
        // 2. 批量查询用户和空间
        Map<Long, List<User>> userIdUserListMap = userService.listByIds(userIdSet).stream()
                .collect(Collectors.groupingBy(User::getId));
        Map<Long, List<Space>> spaceIdSpaceListMap = spaceService.listByIds(spaceIdSet).stream()
                .collect(Collectors.groupingBy(Space::getId));
        // 3. 填充 SpaceUserVO 的用户和空间信息
        spaceUserVOList.forEach(spaceUserVO -> {
            Long userId = spaceUserVO.getUserId();
            Long spaceId = spaceUserVO.getSpaceId();
            // 填充用户信息
            User user = null;
            if (userIdUserListMap.containsKey(userId)) {
                user = userIdUserListMap.get(userId).get(0);
            }
            spaceUserVO.setUser(userService.getUserVO(user));
            // 填充空间信息
            Space space = null;
            if (spaceIdSpaceListMap.containsKey(spaceId)) {
                space = spaceIdSpaceListMap.get(spaceId).get(0);
            }
            spaceUserVO.setSpace(SpaceVO.objToVo(space));
        });
        return spaceUserVOList;
    }

    /**
     * 封装团队空间查询条件QueryWrapper
     *
     * @param spaceUserQueryDTO 团队空间用户查询条件
     * @return QueryWrapper<SpaceUser> 查询条件
     */
    @Override
    public QueryWrapper<SpaceUser> getQueryWrapper(SpaceUserQueryDTO spaceUserQueryDTO) {
        QueryWrapper<SpaceUser> queryWrapper = new QueryWrapper<>();
        if (spaceUserQueryDTO == null) {
            return queryWrapper;
        }
        // 从对象中取值
        Long id = spaceUserQueryDTO.getId();
        Long spaceId = spaceUserQueryDTO.getSpaceId();
        Long userId = spaceUserQueryDTO.getUserId();
        String spaceRole = spaceUserQueryDTO.getSpaceRole();
        // 封装查询条件
        queryWrapper.eq(ObjUtil.isNotEmpty(id), "id", id);
        queryWrapper.eq(ObjUtil.isNotEmpty(spaceId), "spaceId", spaceId);
        queryWrapper.eq(ObjUtil.isNotEmpty(userId), "userId", userId);
        queryWrapper.eq(ObjUtil.isNotEmpty(spaceRole), "spaceRole", spaceRole);
        return queryWrapper;
    }

    /**
     * 团队空间用户信息的基本校验
     *
     * @param spaceUser 空间对象
     */
    @Override
    public void validSpaceUser(SpaceUser spaceUser, Boolean add) {
        ThrowUtils.throwIf(spaceUser == null, ErrorCode.PARAMS_ERROR);
        // 从对象中取值
        Long spaceId = spaceUser.getSpaceId();
        Long userId = spaceUser.getUserId();
        // 如果时创建空间，则进行校验空间 id 和 用户 id 不能为空
        if (add) {
            if (ObjUtil.hasEmpty(spaceId, userId)) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR);
            }
            User user = userService.getById(userId);
            ThrowUtils.throwIf(user == null, ErrorCode.NOT_FOUND_ERROR, "用户不存在");
            Space space = spaceService.getById(spaceId);
            ThrowUtils.throwIf(space == null, ErrorCode.NOT_FOUND_ERROR, "空间不存在");
        }
        // 公共的校验
        // 修改数据时，校验空间角色是否存在
        String spaceRole = spaceUser.getSpaceRole();
        SpaceRoleEnum spaceRoleEnum = SpaceRoleEnum.getEnumByValue(spaceRole);
        if (spaceRole != null && spaceRoleEnum == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "空间角色不存在");
        }
    }
}




